﻿#region Imports
using System.Threading;
#endregion Imports

namespace CommonUtilities.Util
{
    public class SafeCounter
    {
        private int count;

        #region Constructors

        public SafeCounter() { ; }

        public SafeCounter(int value)
            : this()
        {
            this.count = value;
        }

        #endregion Constructors

        #region Public Methods

        public override bool Equals(object other)
        {
            try
            {
                return (bool)(this == (SafeCounter)other);
            }
            catch
            {
                return false;
            }
        }

        public override string ToString()
        {
            return count.ToString();
        }

        public override int GetHashCode()
        {
            return count.GetHashCode();
        }

        #endregion Public Methods

        #region Private Methods

        private int Increment() { return Interlocked.Increment(ref count); }

        private int Decrement() { return Interlocked.Decrement(ref count); }

        private int Add(int toAdd) { return Interlocked.Add(ref count, toAdd); }

        #endregion Private Methods

        #region Operator Overloads

        public static SafeCounter operator +(SafeCounter value, SafeCounter toAdd)
        {
            return value.Add(toAdd);
        }

        public static SafeCounter operator -(SafeCounter value, SafeCounter toSubtract)
        {
            return value.Add(-toSubtract);
        }

        public static SafeCounter operator ++(SafeCounter value)
        {
            return value.Increment();
        }

        public static SafeCounter operator --(SafeCounter value)
        {
            return value.Decrement();
        }

        #endregion Operator Overloads

        #region Implicit Conversions

        public static implicit operator int(SafeCounter value)
        {
            return value.count;
        }

        public static implicit operator SafeCounter(int value)
        {
            return new SafeCounter(value);
        }

        #endregion Implicit Conversions
    }
}
